package pers.xiqingbo.filter;

import pers.xiqingbo.utils.JdbcUtils;

import javax.servlet.*;
import java.io.IOException;

/**
 * @PackageName: ${PACKAGE_NAME}
 * @ClassName: ${NAME}
 * @Description: 事务过滤器
 * @Author: Schieber
 * @Date: 2021/3/4 上午 8:14
 */
public class TransactionFilter implements Filter {
    @Override
    public void destroy() {
    }

    /**
     * 在所有Servlet文件资源添加过滤器，Servlet调用Service中操作数据库的方法时
     * 就等同于Filter间接的调用了Service中操作数据库的方法，过滤链执行完成后，便执行doFilter方法中的后置代码提交事务并关闭连接
     * <p>
     * 如果Service调用方法操作数据时发生异常
     * 则将异常向外层调用者抛出，过滤Servlet的doFilter方法捕获到异常，执行doFilter后置代码中捕获异常代码回滚事务并关闭连接
     * <p>
     * 此方法保证了事务的原子性（sql语句要么都执行，要么都撤销执行）
     *
     * @param req   请求
     * @param resp  响应
     * @param chain 过滤器链
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        try {
            chain.doFilter(req, resp);
            // 未出现异常则提交事务并关闭连接
            JdbcUtils.commitAndClose();
        } catch (Exception e) {
            // 发生异常则回滚事务并关闭连接
            JdbcUtils.rollbackAndClose();
            e.printStackTrace();
            // 将错误抛出给服务器显示错误页面
            throw new RuntimeException(e);
        }
    }

    @Override
    public void init(FilterConfig config) throws ServletException {

    }

}
